﻿/*
 * FightCamera 作用于CameraRoot（第一层）    firstRoot
 * CameraMove 作用于CameraParent（第二层）   secondRoot
 * CameraShake,CameraFOV 作用于MainCamera本体（第三层）thirdRoot
*/
using Share;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Rendering.Universal;



public class CameraMgr : SingletonObject<CameraMgr>
{

    //GameObject m_PlayerCamera;
    private GameObject firstRoot;
    private GameObject secondRoot;
    private GameObject thirdRoot;
    private Vector3 cameraForward = Vector3.zero;
    private float rotateY = 1.0f;
    private float rotateX = 1.0f;
    Camera m_camera;
    Camera m_TempCamera;
    public void SetTempCamera(Camera camera)
    {
        m_TempCamera = camera;
        if (m_TempCamera != null && GetfirstCamera())
            DoShowCamera(true);
    }
    public GameObject GetPlayerCamera()
    {
        if (m_TempCamera != null && m_TempCamera.gameObject.activeInHierarchy)
            return m_TempCamera.gameObject;
        if (thirdRoot == null && Camera.main != null)
            thirdRoot = Camera.main.gameObject;
        return thirdRoot;
    }

    public void SetCameraEnable(bool bValue)
    {
        if (GetCamera())
            GetCamera().enabled = bValue;
    }
    public Camera GetCamera()
    {
        if (m_camera == null && GetPlayerCamera() != null)
            m_camera = GetPlayerCamera().GetComponent<Camera>();
        return m_camera;
    }

    public void SetFirstCamera(GameObject camera)
    {
        firstRoot = camera;
    }

    public bool AutoCreateCamear
    {
        get { return m_bAutoCreateCamear; }
        set { m_bAutoCreateCamear = value; }
    }

    bool m_bAutoCreateCamear = true;
    public GameObject GetfirstCamera()
    {

        if (firstRoot == null && m_bAutoCreateCamear)
        {
            var cameraRoot = GameObject.Find("PassCamera");
            firstRoot = cameraRoot == null ? GameObject.Find("PassCamera(Clone)") : cameraRoot;
            if (cameraRoot == null)
            {
                firstRoot = ObjectMgr.Instance.CreateObj("LogicPrefabs/PassCamera");
            }
            float screenHeight = Display.main.systemHeight;

            // 计算 9:16 比例的宽度
            float targetWidth = screenHeight * TypeDefine.ScreenScale;
            // 设置窗口分辨率（居中显示）
            Screen.SetResolution((int)targetWidth, (int)screenHeight, false);
            // 确保游戏视图比例正确
            Camera.main.aspect = TypeDefine.ScreenScale;
        }
        return firstRoot;
    }

    public void SetfirstCamera(GameObject cam)
    {
        firstRoot = cam.FindDeepChildByName("PassCamera");
        DoFreshCamera();
    }
    // 用来设置摄像机系统的三层结构
    public void SetAllCameras(GameObject firstCamera, GameObject secondCamera, GameObject thirdCamera)
    {
        firstRoot = firstCamera;
        secondRoot = secondCamera;
        thirdRoot = thirdCamera;
        if (thirdRoot)
        {
            m_camera = thirdRoot.GetComponent<Camera>();
        }

    }

    public void SetPlayerCamera(GameObject playerCamera)
    {
        thirdRoot = playerCamera;
    }

    public void SetCameraHDREnable(bool enable)
    {
        GetCamera().allowHDR = enable;
    }



    public void SetCameraDir()
    {
        cameraForward = GetCamera().transform.TransformDirection(Vector3.forward);
    }

    public void ResetCameraDir()
    {
        cameraForward = Vector3.zero;
    }

    public void SetPositionEulerAngles(Vector3 positon, Vector3 localEulerAngles)
    {
        GetfirstCamera().transform.position = positon;
        GetfirstCamera().transform.localEulerAngles = localEulerAngles;
        if (GetPlayerCamera())
        {
            GetPlayerCamera().transform.localPosition = Vector3.zero;
            GetPlayerCamera().transform.localEulerAngles = Vector3.zero;
        }
    }


    public Vector3 GetNowCameraDir()
    {
        //if (cameraForward == Vector3.zero)
        //{
        SetCameraDir();
        //  }

        return cameraForward;
    }

    public void SetRotate(float r1, float r2)
    {
        //rotateX = r1;
        //rotateY = r2;
    }

    public void ResetRotate()
    {
        rotateX = 0.0f;
        rotateY = 0.0f;
    }

    public Vector3 AmendOffset(Vector3 offset)
    {
        if (offset.y < 0)
        {
            offset.x += rotateY;
            offset.y += rotateX;
        }
        else
        {
            offset.x += rotateX;
            offset.y += rotateY;

        }

        if (offset.x < 0)
        {
            if (offset.y < 0)
            {
                offset.x -= rotateY;

            }
            else
            {
                offset.x -= rotateX;
            }
        }
        else if (offset.x > 0)
        {
            if (offset.y < 0)
            {
                offset.x += rotateY;

            }
            else
            {
                offset.x += rotateX;
            }
        }

        offset.Normalize();
        return offset;
    }

    public Vector3 GetFixedDir(Vector3 offset)
    {
        Vector3 forward = GetNowCameraDir();
        forward.y = 0.0f;
        forward = forward.normalized;

        Vector3 right = new Vector3(forward.z, 0, -forward.x);
        offset = AmendOffset(offset);
        return right * offset.x + forward * offset.y;
    }
    bool m_bShowOther = true;
    public bool IsShowOther()
    {
        return m_bShowOther;
    }

    public void SetTimelineCameraMask(GameObject timeline)
    {
        var cam = timeline.GetComponentInChildren<Camera>();
        cam.cullingMask = 1 << LayerMask.NameToLayer("Timeline");

    }
    public void SetGodCameraMask(GameObject timeline)
    {
        var cam = timeline.GetComponentInChildren<Camera>();
        cam.cullingMask &= ~(1 << LayerMask.NameToLayer("Other")); // 不看其他人
        cam.cullingMask |= (1 << LayerMask.NameToLayer("FX"));
        cam.cullingMask |= (1 << LayerMask.NameToLayer("Player"));
    }
    // 隐藏非主角层 Other
    public void DoShowOther(bool bShow)
    {
        if (bShow)
            GetCamera().cullingMask |= (1 << LayerMask.NameToLayer("Other"));
        else
            GetCamera().cullingMask &= ~(1 << LayerMask.NameToLayer("Other"));
        m_bShowOther = bShow;
    }

    public void DoShowPlayer(bool bShow)
    {
        if (bShow)
        {
            GetCamera().cullingMask |= (1 << LayerMask.NameToLayer("Player"));
            GetCamera().cullingMask |= (1 << LayerMask.NameToLayer("FX"));
        }
        else
        {
            GetCamera().cullingMask &= ~(1 << LayerMask.NameToLayer("Player"));
            GetCamera().cullingMask &= ~(1 << LayerMask.NameToLayer("FX"));
        }
    }

    public void DoShowLogicObject(bool bShow)
    {
        if (bShow)
        {
            GetCamera().cullingMask |= (1 << LayerMask.NameToLayer("Other"));
            GetCamera().cullingMask |= (1 << LayerMask.NameToLayer("Player"));
            GetCamera().cullingMask |= (1 << LayerMask.NameToLayer("FX"));
        }
        else
        {
            GetCamera().cullingMask &= ~(1 << LayerMask.NameToLayer("Other"));
            GetCamera().cullingMask &= ~(1 << LayerMask.NameToLayer("Player"));
            GetCamera().cullingMask &= ~(1 << LayerMask.NameToLayer("FX"));
        }
        m_bShowOther = bShow;
    }

    public void DoShowBossTimeline(GameObject timeline)
    {
        var cam = timeline.GetComponentInChildren<Camera>();
        if (cam)
        {
            cam.cullingMask |= (1 << LayerMask.NameToLayer("Default"));
            cam.cullingMask |= (1 << LayerMask.NameToLayer("Player"));
            cam.cullingMask |= (1 << LayerMask.NameToLayer("FX"));
        }

    }
    public void DoEndShowBossTimeline(GameObject timeline)
    {
        var cam = timeline.GetComponentInChildren<Camera>();
        if (cam)
        {
            cam.cullingMask &= ~(1 << LayerMask.NameToLayer("Default"));
            cam.cullingMask &= ~(1 << LayerMask.NameToLayer("Player"));
            cam.cullingMask &= ~(1 << LayerMask.NameToLayer("FX"));
        }

    }

    public void DoShowEffect(bool bShow)
    {
        if (bShow)
        {
            GetCamera().cullingMask |= (1 << LayerMask.NameToLayer("FX"));
        }
        else
        {
            GetCamera().cullingMask &= ~(1 << LayerMask.NameToLayer("FX"));
        }
    }
    PlayableDirector m_playableDirector;
    SmartTimer m_PlayableTimer = new SmartTimer();
    System.Action<PlayableDirector> m_PlayableCallBack;
    public bool IsShowTimeline()
    {
        return m_playableDirector != null;
    }

    public void DoShowCamera(bool value)
    {
        GetCamera().enabled = value;
    }

    Camera m_BaseCamera;

    public void DoInit()
    {
        var cameraRoot = GameObject.Find("PassCamera");
        cameraRoot = cameraRoot == null ? GameObject.Find("PassCamera(Clone)") : cameraRoot;
        if (cameraRoot == null)
        {
            var camera = ObjectMgr.Instance.CreateObj("LogicPrefabs/PassCamera");
            SetfirstCamera(camera);

        }
    }

    public Camera GetBaseCamera()
    {
        if (UIConfig.Instance.UICameraBase == null)
            return null;
        if (m_BaseCamera == null)
        {
            var baseCameraRoot = GameObject.Find("CameraBase");
            if (baseCameraRoot == null)
                baseCameraRoot = ObjectMgr.Instance.CreateObj(UIConfig.Instance.UICameraBase);
            if (baseCameraRoot == null)
                return null;
            m_BaseCamera = baseCameraRoot.GetComponentInChildren<Camera>();
            GameObject.DontDestroyOnLoad(m_BaseCamera);
        }
        return m_BaseCamera;
    }
    Camera m_UICamera;
    public void SetUICamera(Camera uiCamera)
    {
        m_UICamera = uiCamera;
    }

    public Camera GetUICamera()
    {
        return m_UICamera;
    }

    Camera m_FrontCamera = null;
    public void SetFrontCamera(Camera cam)
    {
        m_FrontCamera = cam;
    }

    public void DoRegistToCamera(Camera cam = null)
    {
        DoRegistToCamera(cam, GetBaseCamera());
    }
    public void DoRegistToCamera(Camera cam, Camera baseCamera)
    {
        if (cam == null)
            return;

        var uacd = baseCamera.GetUniversalAdditionalCameraData();
        if (uacd && uacd.cameraStack != null)
        {
            var c = cam.GetUniversalAdditionalCameraData();
            c.renderType = CameraRenderType.Overlay;
            uacd.cameraStack.Add(cam);
        }
    }
    public void DoFreshCamera()
    {
        if (GetBaseCamera() == null)
            return;
        var uacd = GetBaseCamera().GetUniversalAdditionalCameraData();
        uacd.cameraStack.Clear();
        var cameras = Object.FindObjectsByType<Camera>(FindObjectsSortMode.None);
        var tapfxCamera = ScreenTapFxMgr.Instance.GetCamera(); //最上层点击特效相机
        //Camera mainCamera = null;
        if (GetfirstCamera())
        {
            var mainCamera = GetfirstCamera().GetComponentInChildren<Camera>();
            if (mainCamera)
                DoRegistToCamera(mainCamera, GetBaseCamera()); // 场景相机，要放到最底层
        }
        //List<Camera> uiStoryCameras = new List<Camera>();
        //foreach (var cam in cameras)
        //{
        //    if (cam == GetBaseCamera()) // 相机根，不参与显示
        //        continue;
        //    if (cam == m_UICamera) // ui相机，要放到特定的层级
        //        continue;
        //    if (cam == GetfirstCamera())
        //        continue;
        //    DoRegistToCamera(cam, GetBaseCamera());
        //}
        if (m_UICamera != null)
            DoRegistToCamera(m_UICamera, GetBaseCamera());

    }
    /// <summary>
    /// 判断角色是否在相机照射范围内
    /// </summary>
    /// <param name="obj">角色对象</param>
    /// <returns>如果角色在相机照射范围内返回true，否则返回false</returns>
    public bool IsInCameraView(ObjectBase obj)
    {
        Camera camera = GetCamera();
        if (camera == null)
            return false;
        Plane[] planes = GeometryUtility.CalculateFrustumPlanes(camera);
        SkinnedMeshRenderer smr = obj.transform.parent.GetComponentInChildren<SkinnedMeshRenderer>();
        if (smr == null)
            return false;
        if (GeometryUtility.TestPlanesAABB(planes, smr.bounds))
            return true;
        else
            return false;
    }

}

